var htmlparser = require("htmlparser"),
	wikimapiaService = require('../services/wikimapiaService'),
	wikimapiaCategoryService = require('../services/wikimapiaCategoryService'),
	async = require("async");

//argentinaBBox = '-75.014265,-55.919607,-54.359968,-21.853251';
var westLimit = -75.014265,
	northLimit = -55.919607,
	eastLimit = -54.359968,
	southLimit = -21.853251,
	lonDelta = 0.5,
	latDelta = 0.5,
	count = 50,
	category = false,
	west = westLimit,
	north = northLimit,
	east = west + lonDelta,
	south = north + latDelta;

function setBbox(west, north, east, south) {
	return '' + west + ',' + north + ',' + east + ',' + south;
}

function fetchObjects(wikipamiaFolder, callback) {
	if (wikipamiaFolder && wikipamiaFolder.length > 0) {
		console.log("Extrayendo objetos");
		console.log(JSON.stringify(wikipamiaFolder));
		async.forEachSeries(wikipamiaFolder, function (place, callback2) {
			console.log("Call fetchObject: place: " + JSON.stringify(place));
			if (place) {
				fetchObject(place.id, function() {
					callback2();
				});
			} else {
				callback2();
			}
		}, function(err) {
            if (err) callback("ERROR EN forEachSeries" + err);
            else callback(false);
        });
	} else {
		callback(false);
	}
}

function fetchObject(wikipamiaId, callback) {
	wikimapiaService.wikimapiaGetObject(wikipamiaId, function(place) {
		console.log("Obteniendo objeto " + place.id);
		fetchTags(place.tags, function(){
			callback();
		});
	});
}

function fetchTags(wikimapiaTags, callback) {
	if (wikimapiaTags) {
		console.log("Tags obtenidos " + JSON.stringify(wikimapiaTags));
		wikimapiaTags.forEach(function (tag) {
			saveTag(tag.title, function() {
				callback();
			});			
		});
	} else {
		callback();
	}
}


function saveTag(tagId, callback) {
	var tag = {};
	tag.id = tagId;
	wikimapiaService.execute('wikimapia.org', 80, '/object/category/?type=view&id=' + tagId + '&lng=0', 'get', function(response) {
		var dom = parseHtml(response);
		tag.title = dom[2].children[3].children[1].children[3].children[1].children[1].children[1].children[0].children[0].raw.replace(/ \([a-z]{2}\) /g,'');
		wikimapiaService.execute('wikimapia.org', 80, '/object/category/?type=view&id=' + tagId + '&lng=3', 'get', function(response) {
			dom = parseHtml(response);
			tag.title_es = dom[2].children[3].children[1].children[3].children[1].children[1].children[1].children[0].children[0].raw.replace(/ \([a-z]{2}\) /g,'');
			console.log("Categoría de wikimapia recuperada: " + JSON.stringify(tag));
			wikimapiaCategoryService.save(tag, function(err, response) {
				if (err)
					console.log("Error al guardar categoría de wikimapia, id: " + tag.id + " title: " + tag.title.replace(/ \([a-z]{2}\) /g,''));
				else
					console.log("Categoría de wikimapia insertada, id: " + tag.id + " title: " + tag.title.replace(/ \([a-z]{2}\) /g,''));
				callback();
			});
		});
	});
}

function parseHtml(rawHtml) {
	var handler = new htmlparser.DefaultHandler(function (error, dom) {
	    if (error)
	        console.log('Error: ' + error);
	    else
	        console.log('Parsing Done');
	});

	var parser = new htmlparser.Parser(handler);

	parser.parseComplete(rawHtml);

	return handler.dom;
}

function nextBox() {
	west = east;
	east += lonDelta;
	console.log("Bbox: " + setBbox(west, north, east, south));
	if (east > eastLimit) {
		west = westLimit;
		east = west + lonDelta;
		north = south;
		south += latDelta;
	}
}

async.whilst(
    function () { return south <= southLimit; },
    function (callback) {
        var bbox = setBbox(west, north, east, south);
		var page = 1;
		console.log("Buscando página 1 en bbox: " + bbox);
		wikimapiaService.wikimapiaBboxSearch(bbox, category, count, page, function(data) {
			if (data) {
				var cantPages = Math.floor(data.found / 100) + 1;
				fetchObjects(data.folder, function(err) {
					if (err) console.log("ERROR EN fetchObjects: " + err);
					async.whilst(
					    function () { return page < cantPages; },
					    function (callback2) {
					        page++;
							console.log("Buscando página " + page + " en bbox: " + bbox);
							wikimapiaService.wikimapiaBboxSearch(bbox, category, count, page, function(data) {
								fetchObjects(data.folder, function(err) {
									if (err) console.log("ERROR EN fetchObjects: " + err);	
									callback2();
								});
							});
					    },
					    function (err) {
					        if (err) console.log("ERROR EN WHILST: " + err);
					        nextBox();
					        callback();
					    }
					);
				});
			} else {
				nextBox();
				callback();
			}
		});
    },
    function (err) {
        if (err) console.log("ERROR EN WHILST: " + err);
        console.log("Fin del script.");
    }
);